package com.ruicar.afs.cloud.apply.contract.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.apply.business.service.ApplySignRelationService;
import com.ruicar.afs.cloud.apply.common.entity.*;
import com.ruicar.afs.cloud.apply.common.utils.ApplyConstants;
import com.ruicar.afs.cloud.apply.common.utils.ApplyUtils;
import com.ruicar.afs.cloud.apply.contract.enums.CertTypeEnum;
import com.ruicar.afs.cloud.apply.contract.mapper.ApplyContractInfoMapper;
import com.ruicar.afs.cloud.apply.contract.service.*;
import com.ruicar.afs.cloud.apply.contract.vo.*;
import com.ruicar.afs.cloud.apply.pre.approve.service.PreApproveService;
import com.ruicar.afs.cloud.apply.pre.approve.utils.QrCodeUtil;
import com.ruicar.afs.cloud.apply.pre.loan.service.*;
import com.ruicar.afs.cloud.bizcommon.algorithm.enums.CalculateType;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinFinancingItems;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyCostDetailsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyFinancingItemsService;
import com.ruicar.afs.cloud.bizcommon.print.entity.ComPrintFormManage;
import com.ruicar.afs.cloud.bizcommon.print.enums.ServiceClientTypeEnum;
import com.ruicar.afs.cloud.bizcommon.print.service.ComPrintFormManageService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import com.ruicar.afs.cloud.image.enums.AttachmentUniqueCodeEnum;
import com.ruicar.afs.cloud.parameter.commom.entity.TsysAddressParam;
import com.ruicar.afs.cloud.parameter.commom.enums.CostType;
import com.ruicar.afs.cloud.parameter.commom.service.TsysAddressParamService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

// import com.ruicar.afs.cloud.apply.pre.approve.utils.QrCodeUtil;

/**
 * @description: 生成合同模板实现类
 * @author: sijun.yu
 * @date: 2020/7/23 16:23
 */
@Service
@AllArgsConstructor
@Slf4j
public class CreatContractServiceImpl extends ServiceImpl<ApplyContractInfoMapper, ApplyContractInfo> implements CreatContractService {

    private final ComPrintFormManageService comPrintFormManageService;
    private final ApplyOrderInfoService orderInfoService;
    private final ApplyContractInfoService applyContractInfoService;
    private final ApplyCarDetailsService applyCarDetailsService;
    private final ApplyCustBaseInfoService applyCustBaseInfoService;
    private final ApplyCostDetailsService applyCostDetailsService;
    private final ApplyChannelInfoService applyChannelInfoService;
    private final ApplyAddPriceItemsService applyAddPriceItemsService;
    private final ApplyFinancingItemsService applyFinancingItemsService;
    private final ApplySignRelationService applySignRelationService;
    private final ApplyCustPersonalService applyCustPersonalServicel;
    private final ApplyCustAddressDetailsService applyCustAddressDetailsService;
    private final TsysAddressParamService addressParamService;
    private final ApplyCustContactsService applyCustContactsService;
    private final ApplyBankCardService applyBankCardService;
    private final ApplyAffiliatedUnitService applyAffiliatedUnitService;
    private final PreApproveService preApproveService;
    private final ApplyReportService applyReportService;
    private final ApplyCarInvoiceService applyCarInvoiceService;

    /**
     * 获取模板规则数据
     *
     * @param applyNo
     * @return
     */
    private TemplateRuleVO getTemplateRule(String applyNo, String serviceClientType) {

        TemplateRuleVO ruleVO = new TemplateRuleVO();
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        if(orderInfo!=null){
            ruleVO.setBusinessType(orderInfo.getBusinessType());
            ruleVO.setAffiliatedWay(orderInfo.getAffiliatedWay());
            ruleVO.setCarNature(orderInfo.getCarNature());
            ruleVO.setProductId(orderInfo.getProductId());
        }
        ApplyChannelInfo channelInfo = applyChannelInfoService.getChannelInfoByApplyNo(applyNo);
        if(channelInfo!=null){
            ruleVO.setChannelName(channelInfo.getChannelName());
            ApplyCarInvoice carInvoice = applyCarInvoiceService.getApplyCarInvoice(applyNo);
            if(carInvoice!=null){
                if(channelInfo.getChannelName().equals(carInvoice.getInvoiceUnit())){
                    ruleVO.setOfficeEqualDealer("yes");
                }
            }
        }
        ApplyCarDetails carDetails = applyCarDetailsService.getCarDetailsByApplyNo(applyNo);
        if(carDetails!=null){
            ruleVO.setLicenseProvince(carDetails.getLicenseProvince());
            ruleVO.setLicenseCity(carDetails.getLicenseCity());
            ruleVO.setPracticesCity(carDetails.getPurchaseCity());
        }
        ApplyCustBaseInfo custCoBorrower = applyCustBaseInfoService.getCustBaseInfo(applyNo, ApplyConstants.COMMON_BORROWER);
        if(custCoBorrower!=null){
            ruleVO.setHasCommonBorrower("yes");
        }
        ApplyCustBaseInfo custGuarantee = applyCustBaseInfoService.getCustBaseInfo(applyNo, ApplyConstants.GUARANTOR);
        if(custGuarantee!=null){
            ruleVO.setHasBail("yes");
        }
        ApplyBankCard bankCard = applyBankCardService.getBankCardByApplyNo(applyNo);
        if(bankCard!=null){
            ruleVO.setBankCode(bankCard.getBankCode());
        }
        List<FinFinancingItems> itemsList = applyFinancingItemsService.getApplyFinancingItemsList(applyNo);
        if(itemsList!=null && itemsList.size()>0){
            ruleVO.setHasAppend("yes");
        }
        FinCostDetails costDetails = applyCostDetailsService.getApplyCostDetails(applyNo,CostType.CARAMT.getIndex());
        if(carDetails!=null && costDetails.getRepaymentMethod()!=null){
            ruleVO.setRepayMode(costDetails.getRepaymentMethod());
        }
        ruleVO.setServiceClientType(serviceClientType);
        return ruleVO;
    }

    /**
     * 合同信息录入-合同模板参数
     * @param applyNo
     * @return
     */
    public ContractTemplateVO getContractTemplateParam(String applyNo, String serviceClientType){

        BigDecimal addAmt = BigDecimal.ZERO;
        BigDecimal gpsPrice = BigDecimal.ZERO;
        BigDecimal decoratePrice = BigDecimal.ZERO;
        BigDecimal purchaseTaxAmt = BigDecimal.ZERO;
        BigDecimal insuranceAmt = BigDecimal.ZERO;
        BigDecimal gpsAmt = BigDecimal.ZERO;
        BigDecimal decorateAmt = BigDecimal.ZERO;
        BigDecimal boutiqueAmt = BigDecimal.ZERO;
        BigDecimal boutiquePrice = BigDecimal.ZERO;
        BigDecimal tailDownPayAmt = BigDecimal.ZERO;
        BigDecimal tailMonthPayAmt = BigDecimal.ZERO;
        BigDecimal tailPayAmt = BigDecimal.ZERO;
        BigDecimal totalContractAmt = BigDecimal.ZERO;// 合同总价格
        String isPurchaseTax = "□";
        String isInsurance = "□";
        String isGps = "□";
        String isDecorate = "□";
        String isBoutique = "□";
        String noBoutique = "■";
        String noPurchaseTax = "■";
        String noInsurance = "■";
        String noGps = "■";
        String noDecorate = "■";
        String financeItemNames = "";

        List<FinFinancingItems> finFinancingItems = applyFinancingItemsService.getFinancingItemsList(applyNo,null);
        if (finFinancingItems.size() > 0) {
            for (FinFinancingItems financingItems : finFinancingItems) {
                financeItemNames += financingItems.getFinanceItemName() + ":" + (financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt());
                addAmt = addAmt.add(financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt());
                if (financingItems.getFinanceItemCode().equals(ApplyConstants.PURCHASE_TAX)) {
                    isPurchaseTax = "■";
                    noPurchaseTax = "□";
                    purchaseTaxAmt = financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt();
                } else if (financingItems.getFinanceItemCode().equals(ApplyConstants.INSURANCE)) {
                    isInsurance = "■";
                    noInsurance = "□";
                    insuranceAmt = financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt();
                } else if (financingItems.getFinanceItemCode().equals(ApplyConstants.GPS)) {
                    isGps = "■";
                    noGps = "□";
                    gpsAmt = financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt();
                } else if (financingItems.getFinanceItemCode().equals(ApplyConstants.DECORATE)) {
                    isDecorate = "■";
                    noDecorate = "□";
                    decorateAmt = financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt();
                } else if (financingItems.getFinanceItemCode().equals(ApplyConstants.BOUTIQUE)) {
                    isBoutique = "■";
                    noBoutique = "□";
                    boutiqueAmt = financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt();
                }
            }
        }

        List<ApplyAddPriceItems> applyAddPriceItems = applyAddPriceItemsService.getAddPriceItemsList(applyNo);
        for (ApplyAddPriceItems addPriceItems : applyAddPriceItems) {
            if (addPriceItems.getFinanceItemCode().equals(ApplyConstants.GPS)) {
                gpsPrice = addPriceItems.getAddFinanceAmt() == null ? BigDecimal.ZERO : addPriceItems.getAddFinanceAmt();
            } else if (addPriceItems.getFinanceItemCode().equals(ApplyConstants.DECORATE)) {
                decoratePrice = addPriceItems.getAddFinanceAmt() == null ? BigDecimal.ZERO : addPriceItems.getAddFinanceAmt();
            } else if (addPriceItems.getFinanceItemCode().equals(ApplyConstants.BOUTIQUE)) {
                boutiquePrice = addPriceItems.getAddFinanceAmt() == null ? BigDecimal.ZERO : addPriceItems.getAddFinanceAmt();
            }
        }
        // 模板VO
        ContractTemplateVO templateVO = new ContractTemplateVO();
        // 订单信息
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        orderInfo.setCarTypeName(ApplyUtils.dicData(orderInfo.getCarType(), "carType"));
        orderInfo.setBusinessTypeName(ApplyUtils.dicData(orderInfo.getBusinessType(),"businessType"));
        orderInfo.setCarPurposeName(ApplyUtils.dicData(orderInfo.getCarPurpose(),"carPurpose"));
        templateVO.setOrder(orderInfo);
        //发票信息
        ApplyCarInvoice applyCarInvoice=applyCarInvoiceService.getApplyCarInvoice(applyNo);
        templateVO.setCarInvoice(applyCarInvoice);
        // 渠道信息
        ApplyChannelInfo channelInfo = applyChannelInfoService.getChannelInfoByApplyNo(applyNo);
        channelInfo.setReceiptBankName(ApplyUtils.dicData(channelInfo.getReceiptBankCode(),"bank"));
        templateVO.setChannel(channelInfo);
        // 合同信息
        ApplyContractInfo contractInfo = applyContractInfoService.getContractInfoByAppplyNo(applyNo);
        templateVO.setContract(contractInfo);
        // 车辆信息
        ApplyCarDetails carDetails = applyCarDetailsService.getCarDetailsByApplyNo(applyNo);
        templateVO.setCarDetails(carDetails);
        // 主借人信息
        ApplyMainCustVO mainCustVO = this.applyMainCustVO(applyNo, ApplyConstants.PRINCIPAL_BORROWER, true);
        templateVO.setMainCust(mainCustVO);
        // 共借人信息
        ApplyMainCustVO coCustVO = this.applyMainCustVO(applyNo, ApplyConstants.COMMON_BORROWER, false);
        templateVO.setCoCust(coCustVO);
        // 担保人信息
        ApplyMainCustVO bailCustVO = this.applyMainCustVO(applyNo, ApplyConstants.GUARANTOR, false);
        templateVO.setBailCust(bailCustVO);
        //贷款本金
        BigDecimal totalLoanAmt = BigDecimal.ZERO;
        //车辆融资信息
        FinCostDetails carCostDetails = applyCostDetailsService.getApplyCostDetails(applyNo, ApplyConstants.COST_TYPE_CAR_LOAN);
        if (carCostDetails != null) {
            totalLoanAmt = totalLoanAmt.add(carCostDetails.getLoanAmt() == null ? BigDecimal.ZERO : carCostDetails.getLoanAmt());
            tailDownPayAmt = tailDownPayAmt.add(carCostDetails.getDownPayAmt() == null ? BigDecimal.ZERO : carCostDetails.getDownPayAmt());
            tailMonthPayAmt = tailMonthPayAmt.add(carCostDetails.getMonthPayAmt() == null ? BigDecimal.ZERO : carCostDetails.getMonthPayAmt());
            tailPayAmt = tailPayAmt.add(carCostDetails.getTailPayAmt() == null ? BigDecimal.ZERO : carCostDetails.getTailPayAmt());
        }
        templateVO.setCarCost(carCostDetails);
        //附加贷融资信息
        FinCostDetails addCostDetails = applyCostDetailsService.getApplyCostDetails(applyNo, ApplyConstants.COST_TYPE_ADD_LOAN);
        if (addCostDetails != null) {
            totalLoanAmt = totalLoanAmt.add(addCostDetails.getLoanAmt() == null ? BigDecimal.ZERO : addCostDetails.getLoanAmt());
            tailDownPayAmt = tailDownPayAmt.add(addCostDetails.getDownPayAmt() == null ? BigDecimal.ZERO : addCostDetails.getDownPayAmt());
            tailMonthPayAmt = tailMonthPayAmt.add(addCostDetails.getMonthPayAmt() == null ? BigDecimal.ZERO : addCostDetails.getMonthPayAmt());
            tailPayAmt = tailPayAmt.add(addCostDetails.getTailPayAmt() == null ? BigDecimal.ZERO : addCostDetails.getTailPayAmt());
            totalContractAmt = addCostDetails.getContractAmt().add(addAmt);
        }
        templateVO.setTotalContractAmt(totalContractAmt);
        templateVO.setAddCost(addCostDetails);
        templateVO.setTailDownPayAmt(tailDownPayAmt);
        if(CalculateType.equalrental.getValue().equals(carCostDetails.getAlgorithmType())){
            templateVO.setTailMonthPayAmt(tailMonthPayAmt);// 等额本息
        }else if(CalculateType.equalprincipal.getValue().equals(carCostDetails.getAlgorithmType())){
            templateVO.setEqualPrincipalRent(tailMonthPayAmt);// 等额本金
        }else if(CalculateType.structuredloan.getValue().equals(carCostDetails.getAlgorithmType())){
            templateVO.setStructuredLoanRent(tailMonthPayAmt);// 结构化
        }
        templateVO.setTailPayAmt(tailPayAmt);
        //附加产品
        templateVO.setFinanceItemNames(financeItemNames);
        //银行卡信息
        Integer term = 0;
        if (carCostDetails != null && addCostDetails != null) {
            term = carCostDetails.getLoanTerm() > addCostDetails.getLoanTerm() ? carCostDetails.getLoanTerm() : addCostDetails.getLoanTerm();
        } else if (carCostDetails != null) {
            term = carCostDetails.getLoanTerm();
        } else if (addCostDetails != null) {
            term = addCostDetails.getLoanTerm();
        }
        ApplyBankCard applyBankCard = applyBankCardService.getBankCardByApplyNo(applyNo);
        ApplyCustBaseInfo applyCustBaseInfo=applyCustBaseInfoService.getCustInfoByCertNo(applyNo,applyBankCard.getCertNo());
        if(applyCustBaseInfo!=null){
            applyBankCard.setCertPhone(applyCustBaseInfo.getTelPhone());
        }
        applyBankCard.setCertTypeName(CertTypeEnum.IDCARD.getName());
        applyBankCard.setCertType(mainCustVO.getCertType());
        applyBankCard.setDeadlineDate((DateUtil.offset(orderInfo.getRiskPassDate(), DateField.MONTH, term + 4)).toString("yyyy-MM-dd"));
        applyBankCard.setBankName(ApplyUtils.dicData(applyBankCard.getBankCode(),"bank"));
        templateVO.setBankCard(applyBankCard);

        //挂靠信息
        ApplyAffiliatedUnit applyAffiliatedUnit = applyAffiliatedUnitService.getAffiliatedUnitByApplyNo(applyNo);
        if (applyAffiliatedUnit != null) {
            if (StringUtil.isNotBlank(applyAffiliatedUnit.getRegistProvince()) && StringUtil.isNotBlank(applyAffiliatedUnit.getRegistCity())) {
                applyAffiliatedUnit.setRegistDetailAddress(this.provinceOrCity(applyAffiliatedUnit.getRegistProvince()) + this.provinceOrCity(applyAffiliatedUnit.getRegistCity()) + applyAffiliatedUnit.getRegistAddress());
            }
        }
        templateVO.setUnit(applyAffiliatedUnit);

        //增融项信息
        ApplyAddPriceItems addPriceItems = new ApplyAddPriceItems();
        addPriceItems.setIsDecorate(isDecorate);
        addPriceItems.setNoDecorate(noDecorate);
        addPriceItems.setDecorateAmt(decorateAmt);
        addPriceItems.setIsGps(isGps);
        addPriceItems.setNoGps(noGps);
        addPriceItems.setGpsAmt(gpsAmt);
        addPriceItems.setIsInsurance(isInsurance);
        addPriceItems.setNoInsurance(noInsurance);
        addPriceItems.setInsuranceAmt(insuranceAmt);
        addPriceItems.setIsBoutique(isBoutique);
        addPriceItems.setNoBoutique(noBoutique);
        addPriceItems.setBoutiqueAmt(boutiqueAmt);
        addPriceItems.setIsPurchaseTax(isPurchaseTax);
        addPriceItems.setNoPurchaseTax(noPurchaseTax);
        addPriceItems.setPurchaseTaxAmt(purchaseTaxAmt);
        addPriceItems.setGpsPrice(gpsPrice);
        addPriceItems.setDecoratePrice(decoratePrice);
        addPriceItems.setBoutiquePrice(boutiquePrice);
        templateVO.setAddInfo(addPriceItems);
        templateVO.setTotalLoanAmt(totalLoanAmt);
        templateVO.setTotalBigLoanAmt(ApplyUtils.numberToCNMontrayUnit(totalLoanAmt));
        templateVO.setAddAmt(addAmt);
        templateVO.setStartTime(orderInfo.getRiskPassDate());
        templateVO.setEndTime((DateUtil.offset(orderInfo.getRiskPassDate(), DateField.MONTH, term + 3).toString("yyyy-MM-dd")));
        if(AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)){
            templateVO.setPrintDate(DatePattern.CHINESE_DATE_FORMAT.format(new Date()));
        }
        templateVO.setRqCode(QrCodeUtil.creatRrCode(contractInfo.getContractNo(),360,360));
        return templateVO;
    }

    /**
     * 合同信息录入-批量模板生成
     *
     * @param applyNo
     */
    @Override
    public List<ComAttachmentFile> contractBatchPrint(String applyNo,String contractNo,String serviceClientType) {

        // 获取模板参数
        ContractTemplateVO templateVO = getContractTemplateParam(applyNo,serviceClientType);
        // 规则VO
        TemplateRuleVO ruleVO = this.getTemplateRule(applyNo,serviceClientType);
        // 生成模板
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);
        JSONObject jsonRule = (JSONObject) JSONObject.toJSON(ruleVO);
        Assert.isTrue(contractNo!=null,"合同编号不能为空");
        List<ComAttachmentFile> fileList = comPrintFormManageService.batchPrint(jsonTemp, jsonRule, contractNo, "printLoanApply", serviceClientType);
        if (fileList != null && fileList.size() > 0 && AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)) {
            applySignRelationService.saveSignRelationList(fileList,applyNo);
            applyContractInfoService.updateReappearFlag(contractNo);
        }
        return fileList;
    }

    /**
     * 合同信息录入-单个模板
     * @param applyNo
     * @param contractNo
     * @param attachmentFile
     * @return
     */
    public ComAttachmentFile contractSinglePrint(String applyNo,String contractNo,ComAttachmentFile attachmentFile, String serviceClientType){

        // 获取模板参数
        ContractTemplateVO templateVO = getContractTemplateParam(applyNo,serviceClientType);
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);

        ComAttachmentFile comAttachmentFile = comPrintFormManageService.print(jsonTemp,attachmentFile.getAttachmentCode(),contractNo,serviceClientType);
        return comAttachmentFile;
    }

    /**
     * 进件申请-合同模板参数
     * @param applyNo
     * @return
     */
    public ApplyTemplateVO getApplyTemplatePara(String applyNo, String serviceClientType){

        // 模板VO
        ApplyTemplateVO templateVO = new ApplyTemplateVO();
        // 订单信息
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        orderInfo.setCarTypeName(ApplyUtils.dicData(orderInfo.getCarType(), "carType"));
        orderInfo.setBusinessTypeName(ApplyUtils.dicData(orderInfo.getBusinessType(),"businessType"));
        orderInfo.setCarPurposeName(ApplyUtils.dicData(orderInfo.getCarPurpose(),"carPurpose"));
        templateVO.setOrder(orderInfo);
        //发票信息
        ApplyCarInvoice applyCarInvoice=applyCarInvoiceService.getApplyCarInvoice(applyNo);
        templateVO.setCarInvoice(applyCarInvoice);
        // 主借人信息
        ApplyMainCustVO mainCustVO = this.applyMainCustVO(applyNo, ApplyConstants.PRINCIPAL_BORROWER, true);
        templateVO.setMainCust(mainCustVO);
        // 共借人信息
        ApplyMainCustVO coCustVO = this.applyMainCustVO(applyNo, ApplyConstants.COMMON_BORROWER, false);
        templateVO.setCoCust(coCustVO);
        // 担保人信息
        ApplyMainCustVO bailCustVO = this.applyMainCustVO(applyNo, ApplyConstants.GUARANTOR, false);
        templateVO.setBailCust(bailCustVO);
        // 联系人
        List<ApplyCustContacts> contactsList = applyCustContactsService.getCustContactsList(applyNo);
        if(contactsList!=null && contactsList.size()>0){
            for(ApplyCustContacts custContacts:contactsList){
                // 紧急联系人-夫妻
                String custRelation = custContacts.getCustRelation();
                if(ApplyConstants.SPOUSE.equals(custRelation)){
                    ApplyCustContacts spouseCustVO = new ApplyCustContacts();
                    BeanUtils.copyProperties(custContacts, spouseCustVO);
                    if (StringUtil.isNotBlank(spouseCustVO.getLivingProvince()) && StringUtil.isNotBlank(spouseCustVO.getLivingCity())) {
                        spouseCustVO.setLivingDetailAddress(this.provinceOrCity(spouseCustVO.getLivingProvince()) + this.provinceOrCity(spouseCustVO.getLivingCity()) + (spouseCustVO.getDetailAddress() == null ? "" : spouseCustVO.getDetailAddress()));
                    }
                    templateVO.setSpouseCust(spouseCustVO);
                }
                // 紧急联系人-父母或其他亲属
                else if(ApplyConstants.PARENT.equals(custRelation)||ApplyConstants.BROTHER.equals(custRelation)||ApplyConstants.FAMILY.equals(custRelation)||ApplyConstants.OTHER.equals(custRelation)){
                    ApplyCustContacts parentCusVo = new ApplyCustContacts();
                    BeanUtils.copyProperties(custContacts, parentCusVo);
                    // 与主借人关系
                    parentCusVo.setCustRelation(ApplyUtils.dicData(custRelation, "custRelation"));
                    if (StringUtil.isNotBlank(parentCusVo.getLivingProvince()) && StringUtil.isNotBlank(parentCusVo.getLivingCity())) {
                        parentCusVo.setLivingDetailAddress(this.provinceOrCity(parentCusVo.getLivingProvince()) + this.provinceOrCity(parentCusVo.getLivingCity()) + (parentCusVo.getDetailAddress() == null ? "" : parentCusVo.getDetailAddress()));
                    }
                    templateVO.setParentCust(parentCusVo);
                }
                //紧急联系人-其他联系人
                else if(ApplyConstants.FRIEND.equals(custRelation)||ApplyConstants.ENTERPRISE_THIRD.equals(custRelation)||ApplyConstants.SUPPLIER.equals(custRelation)||ApplyConstants.BANK_FACTORING.equals(custRelation)
                        ||ApplyConstants.PERSONAL_THIRD.equals(custRelation)||ApplyConstants.COLLEAGUE.equals(custRelation)){
                    ApplyCustContacts otherCustVo = new ApplyCustContacts();
                    BeanUtils.copyProperties(custContacts, otherCustVo);
                    otherCustVo.setCustRelation(ApplyUtils.dicData(custRelation, "custRelation"));
                    if (StringUtil.isNotBlank(otherCustVo.getLivingProvince()) && StringUtil.isNotBlank(otherCustVo.getLivingCity())) {
                        otherCustVo.setLivingDetailAddress(this.provinceOrCity(otherCustVo.getLivingProvince()) + this.provinceOrCity(otherCustVo.getLivingCity()) + (otherCustVo.getDetailAddress() == null ? "" : otherCustVo.getDetailAddress()));
                    }
                    templateVO.setOtherCust(otherCustVo);
                }
            }
        }

        // 车款融资信息
        BigDecimal totalContractAmt = BigDecimal.ZERO;
        BigDecimal totalLoanAmt = BigDecimal.ZERO;
        FinCostDetails carCostDetails = applyCostDetailsService.getApplyCostDetails(applyNo, ApplyConstants.COST_TYPE_CAR_LOAN);
        if (carCostDetails != null) {
            totalContractAmt = totalContractAmt.add(carCostDetails.getContractAmt() == null ? BigDecimal.ZERO : carCostDetails.getContractAmt());
            totalLoanAmt = totalLoanAmt.add(carCostDetails.getLoanAmt() == null ? BigDecimal.ZERO : carCostDetails.getLoanAmt());
        }
        templateVO.setCarCost(carCostDetails);
        // 附加贷融资信息
        FinCostDetails addCostDetails = applyCostDetailsService.getApplyCostDetails(applyNo, ApplyConstants.COST_TYPE_ADD_LOAN);
        if (addCostDetails != null) {
            totalContractAmt = totalContractAmt.add(addCostDetails.getContractAmt() == null ? BigDecimal.ZERO : addCostDetails.getContractAmt());
            totalLoanAmt = totalLoanAmt.add(addCostDetails.getLoanAmt() == null ? BigDecimal.ZERO : addCostDetails.getLoanAmt());
        }
        // 合同价格
        templateVO.setTotalContractAmt(totalContractAmt);
        // 贷款金额
        templateVO.setTotalLoanAmt(totalLoanAmt);
        templateVO.setAddCost(addCostDetails);
        // 车辆信息
        ApplyCarDetails carDetails = applyCarDetailsService.getCarDetailsByApplyNo(applyNo);
        carDetails.setLicenseDetail(this.provinceOrCity(carDetails.getLicenseProvince()) + this.provinceOrCity(carDetails.getLicenseCity()));
        templateVO.setCarDetails(carDetails);
        // 渠道信息
        ApplyChannelInfo channelInfo = applyChannelInfoService.getChannelInfoByApplyNo(applyNo);
        channelInfo.setReceiptBankName(ApplyUtils.dicData(channelInfo.getReceiptBankCode(),"bank"));
        templateVO.setChannel(channelInfo);
        // 附加品金额
        List<FinFinancingItems> finFinancingItemsList = applyFinancingItemsService.getFinancingItemsList(applyNo,carDetails.getId());
        BigDecimal addAmt = BigDecimal.ZERO;
        if (finFinancingItemsList.size() > 0) {
            for (FinFinancingItems financingItems : finFinancingItemsList) {
                addAmt = addAmt.add(financingItems.getFinanceItemAmt() == null ? BigDecimal.ZERO : financingItems.getFinanceItemAmt());
            }
        }
        templateVO.setAddAmt(addAmt);
        if(AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)){
            templateVO.setPrintDate(DatePattern.CHINESE_DATE_FORMAT.format(new Date()));
        }
        templateVO.setRqCode(QrCodeUtil.creatRrCode(orderInfo.getId().toString(),360,360));
        return templateVO;
    }

    /**
     * 进件申请-批量模板生成
     *
     * @param applyNo
     */
    @Override
    public List<ComAttachmentFile> applyBatchPrint(String applyNo,String serviceClientType) {

        // 获取模板参数
        ApplyTemplateVO templateVO = this.getApplyTemplatePara(applyNo,serviceClientType);

        // 规则VO
        TemplateRuleVO ruleVO = this.getTemplateRule(applyNo,serviceClientType);

        // 生成模板
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);
        JSONObject jsonRule = (JSONObject) JSONObject.toJSON(ruleVO);
        List<ComAttachmentFile> fileList = comPrintFormManageService.batchPrint(jsonTemp, jsonRule, applyNo, "printOrderApply", serviceClientType);
        if (fileList != null && fileList.size() > 0 && AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)) {
            applySignRelationService.saveSignRelationList(fileList,applyNo);
            applyReportService.updateReappearFlag(applyNo);
        }
        return fileList;
    }

    /**
     * 进件申请-单个模板生成
     * @param applyNo
     * @param attachmentFile
     * @return
     */
    public ComAttachmentFile applySinglePrint(String applyNo,ComAttachmentFile attachmentFile,String serviceClientType){

        // 获取模板参数
        ApplyTemplateVO templateVO = this.getApplyTemplatePara(applyNo,serviceClientType);
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);
        ComAttachmentFile comAttachmentFile = comPrintFormManageService.print(jsonTemp,attachmentFile.getAttachmentCode(),applyNo,serviceClientType);
        return comAttachmentFile;
    }

    /**
     * 进件申请-单个模板生成
     * @param applyNo
     * @param attachmentFile
     * @return
     */
    @Override
    public ComAttachmentFile applySinglePrintByCustId(String applyNo, ComAttachmentFile attachmentFile, String serviceClientType){

        // 获取模板参数
        ApplyTemplateVO templateVO = this.getApplyTemplatePara(applyNo,serviceClientType);
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);
        ComAttachmentFile comAttachmentFile = comPrintFormManageService.print(jsonTemp,attachmentFile.getAttachmentCode(),applyNo,serviceClientType);
        return comAttachmentFile;
    }

    /**
     * 进件征信授权书-模板生成
     *
     * @param applyNo
     */
    public List<ComAttachmentFile> applyAuthorBatchPrint(String busiType,String applyNo,String certNo,String serviceClientType) {

        List<ComAttachmentFile> fileList = new ArrayList<ComAttachmentFile>();
        // 模板VO
        ApplyTemplateVO templateVO = new ApplyTemplateVO();
        if(AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)){
            templateVO.setPrintDate(DatePattern.CHINESE_DATE_FORMAT.format(new Date()));
        }
        ApplyCustBaseInfo applyCustBaseInfo = applyCustBaseInfoService.getCustInfoByCertNo(applyNo,certNo);
        Assert.isTrue(applyCustBaseInfo!=null,"客户信息不能为空");
        // 主借人信息
        if(ApplyConstants.PRINCIPAL_BORROWER.equals(applyCustBaseInfo.getCustRole())){
            ComPrintFormManage comPrintFormManage = comPrintFormManageService.getPrintFormManageByUniqueCode(AttachmentUniqueCodeEnum.MAIN_BORROWER_CREDIT_FILE.getCode());
            Assert.isTrue(comPrintFormManage!=null,"主借人征信授权书不存在");
            ApplyMainCustVO mainCustVO = this.applyMainCustVO(applyNo, ApplyConstants.PRINCIPAL_BORROWER, true);
            templateVO.setMainCust(mainCustVO);
            JSONObject originJson = (JSONObject) JSONObject.toJSON(templateVO);
            ComAttachmentFile attachmentFile = comPrintFormManageService.print(originJson, comPrintFormManage.getId().toString(), applyNo, serviceClientType);
            if(attachmentFile!=null){
                fileList.add(attachmentFile);
            }
        }
        // 共借人信息
        else if(ApplyConstants.COMMON_BORROWER.equals(applyCustBaseInfo.getCustRole())){
            ComPrintFormManage comPrintFormManage = comPrintFormManageService.getPrintFormManageByUniqueCode(AttachmentUniqueCodeEnum.COM_BORROWER_CREDIT_FILE.getCode());
            Assert.isTrue(comPrintFormManage!=null,"共借人征信授权书不存在");
            ApplyMainCustVO coCustVO = this.applyMainCustVO(applyNo, ApplyConstants.COMMON_BORROWER, false);
            templateVO.setCoCust(coCustVO);
            JSONObject originJson = (JSONObject) JSONObject.toJSON(templateVO);
            ComAttachmentFile attachmentFile = comPrintFormManageService.print(originJson, comPrintFormManage.getId().toString(), applyNo, serviceClientType);
            if(attachmentFile!=null){
                fileList.add(attachmentFile);
            }
        }
        // 担保人信息
        else if(ApplyConstants.GUARANTOR.equals(applyCustBaseInfo.getCustRole())){
            ComPrintFormManage comPrintFormManage = comPrintFormManageService.getPrintFormManageByUniqueCode(AttachmentUniqueCodeEnum.GUARANTOR_BORROWER_CREDIT_FILE.getCode());
            Assert.isTrue(comPrintFormManage!=null,"保证人征信授权书不存在");
            ApplyMainCustVO bailCustVO = this.applyMainCustVO(applyNo, ApplyConstants.GUARANTOR, false);
            templateVO.setBailCust(bailCustVO);
            JSONObject originJson = (JSONObject) JSONObject.toJSON(templateVO);
            ComAttachmentFile attachmentFile = comPrintFormManageService.print(originJson, comPrintFormManage.getId().toString(), applyNo, serviceClientType);
            if(attachmentFile!=null){
                fileList.add(attachmentFile);
            }
        }
        if (fileList != null && fileList.size() > 0 && AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)) {
            applySignRelationService.saveSignRelationList(fileList,applyNo);
        }
        return fileList;
    }

    /**
     * 预审批-模板参数
     * @param busiType
     * @param id
     * @return
     */
    public PreAuthorTemplateVO getPreAuthorTemplatePara(String busiType, Long id){

        // 模板VO
        PreAuthorTemplateVO templateVO = new PreAuthorTemplateVO();
        // 订单信息
        PreApproveInfo preApproveInfo = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda().eq(PreApproveInfo::getId, id).eq(PreApproveInfo::getBusinessType, busiType));
        templateVO.setPreInfo(preApproveInfo);
        return templateVO;
    }

    /**
     * 预审批-批量模板生成
     * @param busiType
     * @param id
     * @return
     */
    public List<ComAttachmentFile> preAuthorBatchPrint(String busiType, Long id, String serviceClientType) {

        // 获取模板参数
        PreAuthorTemplateVO  templateVO = this.getPreAuthorTemplatePara(busiType,id);
        // 规则VO
        TemplateRuleVO ruleVO = new TemplateRuleVO();
        ruleVO.setBusinessType(busiType);
        ruleVO.setServiceClientType(serviceClientType);
        // 生成模板
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);
        JSONObject jsonRule = (JSONObject) JSONObject.toJSON(ruleVO);
        log.info(jsonRule.toString());
        List<ComAttachmentFile> fileList = comPrintFormManageService.batchPrint(jsonTemp, jsonRule, id.toString(), "printPreApply",serviceClientType);
        if(fileList!=null && fileList.size()>0 && AfsEnumUtil.key(ServiceClientTypeEnum.APP).equals(serviceClientType)){
            applySignRelationService.savePreRelationList(fileList);
        }
        return fileList;
    }

    /**
     * 预审批-单个模板生成
     * @param busiType
     * @param busiNo
     * @param attachmentFile
     * @return
     */
    public ComAttachmentFile preAuthorSinglePrint(String busiType, String busiNo,ComAttachmentFile attachmentFile, String serviceClientType){

        // 获取模板参数
        PreAuthorTemplateVO  templateVO = this.getPreAuthorTemplatePara(busiType,Long.valueOf(busiNo));
        JSONObject jsonTemp = (JSONObject) JSONObject.toJSON(templateVO);
        ComAttachmentFile comAttachmentFile = comPrintFormManageService.print(jsonTemp,attachmentFile.getAttachmentCode(), busiNo, serviceClientType);
        return comAttachmentFile;
    }

    /**
     * 翻译省份城市
     */
    public String provinceOrCity(String provinceOrCity) {

        TsysAddressParam province = addressParamService.getProvinceOrCtiy(provinceOrCity);
        return province.getLabel();
    }

    /**
     * 主共保信息
     * @param applyNo
     * @param custRule
     * @param flag
     * @return
     */
    public ApplyMainCustVO applyMainCustVO(String applyNo, String custRule, boolean flag) {

        ApplyCustBaseInfo applyMainCustInfo = applyCustBaseInfoService.getCustBaseInfo(applyNo, custRule);
        ApplyMainCustVO mainCustVO = new ApplyMainCustVO();
        if (applyMainCustInfo != null) {
            BeanUtils.copyProperties(applyMainCustInfo, mainCustVO);
            //现居住地址
            ApplyCustAddressDetails applyCustAddressDetails = applyCustAddressDetailsService.getApplyCustAddressDetails(applyMainCustInfo.getId(), ApplyConstants.RESIDENTIAL_ADDRESS);
            if (applyCustAddressDetails != null) {
                //房产类型
                mainCustVO.setHouseType(ApplyUtils.dicData(applyCustAddressDetails.getHouseType(), "houseType"));
                mainCustVO.setPostalCode(applyCustAddressDetails.getPostalCode());
                mainCustVO.setLivingAddress(this.provinceOrCity(applyCustAddressDetails.getProvince()) + this.provinceOrCity(applyCustAddressDetails.getCity()) + (applyCustAddressDetails.getDetailAddress() == null ? "" : applyCustAddressDetails.getDetailAddress()));
                if (applyCustAddressDetails.getIsDefault().equals(ApplyConstants.IS_SUB_PRODUCT)) {
                    mainCustVO.setMailingAddress(mainCustVO.getLivingAddress());
                }
            }
            //单位地址
            ApplyCustAddressDetails addressDetails = applyCustAddressDetailsService.getApplyCustAddressDetails(applyMainCustInfo.getId(), ApplyConstants.COMPANY_ADDRESS);
            if (addressDetails != null) {
                mainCustVO.setWorkingAddress(this.provinceOrCity(addressDetails.getProvince()) + this.provinceOrCity(addressDetails.getCity()) + (addressDetails.getDetailAddress() == null ? "" : addressDetails.getDetailAddress()));
                if (addressDetails.getIsDefault().equals(ApplyConstants.IS_SUB_PRODUCT)) {
                    mainCustVO.setMailingAddress(mainCustVO.getWorkingAddress());
                }
            }
            //查询客户明细
            ApplyCustPersonalDetail applyCustPersonalDetail = applyCustPersonalServicel.getCustPersonalDetail(applyNo, applyMainCustInfo.getId());
            if (applyCustPersonalDetail != null) {
                BeanUtils.copyProperties(applyCustPersonalDetail, mainCustVO);
                //婚姻状态
                mainCustVO.setMaritalStatus(ApplyUtils.dicData(applyCustPersonalDetail.getMaritalStatus(), "maritalStatus"));
                //性别
                mainCustVO.setSex(ApplyUtils.dicData(applyCustPersonalDetail.getSex(), "sex"));
                //最高学历
                mainCustVO.setHighestEducation(ApplyUtils.dicData(applyCustPersonalDetail.getHighestEducation(), "highestEducation"));
                //行业类型
                mainCustVO.setIndustryType(ApplyUtils.dicData(applyCustPersonalDetail.getIndustryType(), "industryType"));
                //职业类型
                mainCustVO.setJobsType(ApplyUtils.dicData(applyCustPersonalDetail.getJobsType(), "jobsType"));
                //职位
                mainCustVO.setPosition(ApplyUtils.dicData(applyCustPersonalDetail.getPosition(), "position"));
            }
            //证件类型
            mainCustVO.setCertType(ApplyUtils.dicData(applyMainCustInfo.getCertType(), "certType"));
            if (flag) {
                //主借人户口
                mainCustVO.setIsLocalAccount("本地户口");
            } else {
                //与主借人关系
                mainCustVO.setCustRelation(ApplyUtils.dicData(applyMainCustInfo.getCustRelation(), "custRelation"));
            }
        }
        return mainCustVO;
    }
}
